home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS04.ADF
/
C
/
gfxmem.c
< prev
next >
Wrap
C/C++ Source or Header
|
1985-11-03
|
8KB
|
279 lines
/*
Path: puff!uwvax!harvard!seismo!caip!louie
From: louie@trantor.UMD.EDU
Subject: gfxmem.c - graphical memory usage for your amiga
Date: 28 Oct 85 05:26:32 GMT
Organization: Rutgers Univ., New Brunswick, N.J.
From: Louis A. Mamakos <louie@trantor.UMD.EDU>
Here's a program that I hacked together today to figure out how some of the
graphics primitives work. It creates a window, and plots a bar graph in it
showing how much memory is free and how much is in use. If you have so
called FAST memory external, then it's size is displayed too.
As you resize the window, the bar graphs are rescaled. This program shows
you how to create a window, and how to use the RectFill() function. You'll
also see how to handle some of the Intuition messages about your window. I
wasn't able to make the timer.device thingy work, so there's a bit of a
kludge in there to use AmigaDOS Delay() subroutine.
Oh well, it just a day's hack anyway. The hack to find how much memory is in
the system is from Amiga's AVAIL program. I don't claim to know how it
works; it's methods certainly aren't documented. Enjoy.
*/
/*
* gfxmem.c - display memory used graphically. This program is a freebie;
* give it to anyone you want, just don't sell it. If you do, the software
* police will be out to get YOU!
*
* Copyright (C) 1985, Louis A. Mamakos
*/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/exec.h>
#include <exec/execbase.h>
#include <exec/ports.h>
#include <exec/devices.h>
#include <exec/memory.h>
#include <devices/timer.h>
#include <hardware/blit.h>
#include <graphics/copper.h>
#include <graphics/regions.h>
#include <graphics/rastport.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/gels.h>
#include <intuition/intuition.h>
extern struct ExecBase *SysBase;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct MsgPort *timerport, *CreatePort();
struct timerequest timereq;
struct NewWindow NewWindow = {
10, 10, 400, 50, /* sizes */
0, 1, /* pens */
CLOSEWINDOW | SIZEVERIFY | NEWSIZE | REFRESHWINDOW,/* IDCMP flags */
WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | WINDOWSIZING | SIMPLE_REFRESH,
NULL, NULL, /*gadget, checkmark */
"GfxMem", /* title */
NULL, NULL, /* screen, bitmap */
100, 30, 640, 60, /* min and max sizing */
WBENCHSCREEN /* on the workbench screen */
};
ULONG AvailMem ();
ULONG ChipMax, FastMax, ChipFree, FastFree;
ULONG ChipLargest, FastLargest;
int dont_draw;
/*
* maxsize -- determine the total maximum size for all regions
* of the given type. This code must be executed while
* FORBIDDEN (it accesses shared system structures).
*/
ULONG
maxsize (t)
unsigned long t;
{
/* THIS CODE MUST ALWAYS BE CALLED WHILE FORBIDDEN */
ULONG size = 0;
struct MemHeader *mem;
struct ExecBase *eb = SysBase;
for (mem = (struct MemHeader *) eb -> MemList.lh_Head;
mem -> mh_Node.ln_Succ; mem = mem -> mh_Node.ln_Succ)
if (mem -> mh_Attributes & t)
size += ((ULONG) mem -> mh_Upper - (ULONG) mem -> mh_Lower);
return size;
}
getsizes()
{
if (ChipMax == 0) { /* only do this once */
Forbid ();
ChipMax = maxsize (MEMF_CHIP);
FastMax = maxsize (MEMF_FAST);
Permit();
}
ChipFree = AvailMem (MEMF_CHIP);
ChipLargest = AvailMem (MEMF_CHIP | MEMF_LARGEST);
FastFree = AvailMem (MEMF_FAST);
FastLargest = AvailMem (MEMF_FAST | MEMF_LARGEST);
}
starttimer()
{
timereq.tr_time.tv_secs = 1;
timereq.tr_time.tv_micro = 0;
timereq.tr_node.io_Command = TR_ADDREQUEST;
timereq.tr_node.io_Flags = 0;
timereq.tr_node.io_Error = 0;
DoIO((char *) &timereq.tr_node);
}
/*
* Main function. Call intution to create a new window for us on the
* screen. Go from there.
*/
main(argc, argv)
int argc;
char **argv;
{
struct Window *w;
struct IntuiMessage *msg, *GetMsg();
struct MsgPort *timerport, *CreatePort();
static struct timerequest timereq;
timerport = NULL;
IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 0);
if (IntuitionBase == NULL)
exit(1);
GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
if (GfxBase == NULL) {
CloseLibrary(IntuitionBase);
exit(2);
}
if ((w = (struct Window *) OpenWindow(&NewWindow)) == NULL) {
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
exit(3);
}
if ((timerport = CreatePort("Timer Port", 0)) == NULL) {
CloseWindow(w);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
exit(5);
}
timereq.tr_node.io_Message.mn_ReplyPort = timerport;
timereq.tr_node.io_Message.mn_Length = sizeof (timereq);
timereq.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
timereq.tr_node.io_Message.mn_Node.ln_Pri = 0;
timereq.tr_node.io_Message.mn_Node.ln_Succ = NULL;
timereq.tr_node.io_Message.mn_Node.ln_Pred = NULL;
timereq.tr_node.io_Error = 0;
timereq.tr_node.io_Flags = 0;
if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &timereq, 0) != 0) {
DeletePort(timerport);
CloseWindow(w);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
exit(4);
}
redraw(w, TRUE);
/* starttimer(); */
for(;;) {
#ifdef notdef
Wait((1 << w->UserPort->mp_SigBit) |
(1 << timerport->mp_SigBit));
#endif
/*
* Next two lines are a kludge; if I can figure out how to make the timer
* device work, than that's the right way to do it. Oh well...
*/
Delay(25);
redraw(w, FALSE);
while (msg = GetMsg(w->UserPort)) {
switch (msg->Class) {
case CLOSEWINDOW:
ReplyMsg(msg);
CloseDevice(&timereq);
DeletePort(timerport);
CloseWindow(w);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
exit(0);
case REFRESHWINDOW:
BeginRefresh(w);
dont_draw = 0;
redraw(w, TRUE);
EndRefresh(w, TRUE);
case NEWSIZE:
dont_draw = 0;
redraw(w, FALSE);
break;
case SIZEVERIFY:
dont_draw = 1;
break;
}
ReplyMsg(msg);
} /* while */
if (GetMsg(timerport)) {
redraw(w, FALSE);
starttimer();
}
} /* for */
}
#define TOP w->BorderTop
#define BOTTOM w->Height - w->BorderBottom
#define LEFT w->BorderLeft
#define RIGHT w->Width - w->BorderRight
#define GUTTER 3 /* pixels of veritical spacing between bars */
/*
* Redraw all of the stuff in the window.
*/
redraw(w, refresh)
struct Window *w;
int refresh;
{
register struct RastPort *rp = w->RPort;
register short x_min, y_min, x_max, y_max;
static short AvailWidth, AvailHeight, HorizSpace, Thickness, Scale;
if (dont_draw)
return 0;
getsizes();
if (refresh) {
SetAPen(rp, 2);
SetBPen(rp, 2);
SetOPen(rp, 2);
RectFill(rp, LEFT, TOP, RIGHT, BOTTOM);
/* recalculate the spacing paramters for this sized window */
AvailWidth = w->Width - w->BorderRight - w->BorderLeft;
AvailHeight = w->Height - w->BorderTop - w->BorderBottom;
HorizSpace = AvailWidth/20; /* use 5% of available space as margin */
AvailWidth -= HorizSpace * 2;
Thickness = (AvailHeight - GUTTER*3) / 2;
if (ChipMax > FastMax)
Scale = ChipMax/AvailWidth;
else
Scale = FastMax/AvailWidth;
}
SetAPen(rp, 3);
SetOPen(rp, 1);
SetBPen(rp, 2);
x_min = HorizSpace;
y_min = TOP + GUTTER;
x_max = x_min + (ChipMax - ChipFree)/Scale;
y_max = y_min + Thickness;
RectFill(rp, x_min, y_min, x_max, y_max);
x_min = x_max;
x_max = x_min + ChipFree/Scale;
SetAPen(rp, 0);
RectFill(rp, x_min, y_min, x_max, y_max);
x_min = HorizSpace;
x_max = x_min + (FastMax - FastFree)/Scale;
y_min = y_max + GUTTER;
y_max = y_min + Thickness;
SetAPen(rp, 3);
RectFill(rp, x_min, y_min, x_max, y_max);
x_min = x_max;
x_max = x_min + FastFree/Scale;
SetAPen(rp, 0);
RectFill(rp, x_min, y_min, x_max, y_max);
}